package com.shangxia.lucky.lucky.job.write;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.shangxia.lucky.lucky.ConfigText;
import com.shangxia.lucky.lucky.common.FactoryHead;
import com.shangxia.lucky.lucky.writeHandler.MyOverThreadExcelWriteHandler;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;

import java.util.*;

/**
 * @ProjectName: monomer
 * @ClassName: OverWriterThread
 * @Time: 2021/9/4
 * @Author: zhouy
 * @Description:
 * @Experience:
 */

@Slf4j
@Data
@NoArgsConstructor
public class OverWriterThread implements Runnable ,ExportThreadJobOver{


    public volatile static boolean WRITER_OVER_LOG = false;
    private Integer maxColumn;
    private Integer codeLength;
    private String filePath;
    public Boolean overWriteFlag;
    public final static Map<Integer, LinkedList<List<List<String>>>> mapQueue = new HashMap<>();
    public static Map<Integer, MyOverThreadExcelWriteHandler> WRITE_HANDLERS_MAP = new HashMap<>();

    public static List<Integer> EXPORT_COLUMNS = new ArrayList<>();

    public ConfigText configText;

    public OverWriterThread(ConfigText configText) {
        this.maxColumn = configText.getBananaExportColumn();
        this.codeLength = configText.getBananaCodeLength();
        this.filePath = configText.getBananaAbsoluteResultPath();
        overWriteFlag = configText.getBananaOverExportOpen();
        if (!overWriteFlag) {
            WRITER_OVER_LOG = true;
        }
        this.configText = configText;
        initExportColumns();
        initMapQueue();
    }


    @Override
    public void run() {
        if (!getOverWriteFlag()) {
            return;
        }
        Map<Integer, WriteSheet> writeSheetMap = new HashMap<>();
        //
        Map<Integer, Integer> map = new HashMap<>();
        for (Integer exportColumn : EXPORT_COLUMNS) {
            writeSheetMap.put(exportColumn, EasyExcel.writerSheet(exportColumn, "第" + (exportColumn + 1) + "层")
                    .registerWriteHandler(WRITE_HANDLERS_MAP.get(exportColumn))
                    .head(FactoryHead.head(exportColumn, codeLength)).build());
            map.put(exportColumn, 0);
        }
        String overFile = filePath + DateFormatUtils.format(new Date(), "yyyy-MM-dd_H-mm-ss_翻层表") + ".xlsx";
        ExcelWriter excelWriter = EasyExcel.write(overFile).build();
        log.info("翻层输出 开始");

        while (getOverWriteFlag() || !checkQueueIsEmpty()) {
            for (Integer column : mapQueue.keySet()) {
                List<List<String>> lists = mapQueue.get(column).poll();
                if (null != lists) {
                    excelWriter.write(lists, writeSheetMap.get(column));
                    map.put(column, map.get(column) + lists.size());
                    if (map.get(column) % 1000 == 0) {
                        log.info("输出第" + (column + 1) + "层 第" + map.get(column) + "行");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        excelWriter.finish();
        WRITER_OVER_LOG = true;
        log.info("--------------翻层输出 结束----------------");
    }

    public void initExportColumns() {
        if (StringUtils.isEmpty(configText.getBananaExportColumns())) {
            for (int i = 0; i < configText.getBananaExportColumn(); i++) {
                EXPORT_COLUMNS.add(i);
            }
            return;
        }
        String[] columns = configText.getBananaExportColumns().split(",");
        Arrays.stream(columns).forEach(column -> {
            if (!column.contains("-")) {
                EXPORT_COLUMNS.add(Integer.parseInt(column.trim()) - 1);
            } else {
                String[] nums = column.split("-");
                for (int num = Integer.parseInt(nums[0].trim()); num <= Integer.parseInt(nums[1].trim()); num++) {
                    EXPORT_COLUMNS.add(num - 1);
                }
            }
        });
    }

    private void initMapQueue() {
        for (Integer exportColumn : EXPORT_COLUMNS) {
            mapQueue.put(exportColumn, new LinkedList<>());
            WRITE_HANDLERS_MAP.put(exportColumn, new MyOverThreadExcelWriteHandler(new ArrayList<>()));
        }
    }

    public Boolean checkQueueIsEmpty() {
        for (LinkedList<List<List<String>>> value : mapQueue.values()) {
            if (!value.isEmpty()) {
                return false;
            }
        }
        return true;
    }

    public void stop() {
        setOverWriteFlag(Boolean.FALSE);
    }

    @Override
    public Boolean over() {
        return null;
    }
}
